package com.qzl.feiq.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.AbstractEventExecutorGroup;
import com.qzl.feiq.config.FeiQCache;
import com.qzl.feiq.config.StaticConfig;
import com.qzl.feiq.protocol.TcpSimple2Message;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Objects;
import java.util.Set;

public class TcpServer {
    private static NioEventLoopGroup bossGroup = new NioEventLoopGroup();
    private static NioEventLoopGroup workerGroup = new NioEventLoopGroup();

    public static void main(String[] args) throws InterruptedException {
        init();
    }
    public static void start(){
        Set<String> ips = FeiQCache.allIps;
        ips.forEach(ip -> {
            try {
                Channel channel = new ServerBootstrap()
                        .group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .localAddress(ip, StaticConfig.TCP_PORT)
                        .childHandler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            protected void initChannel(SocketChannel ch) throws Exception {
                                // 可以直接处理感兴趣的类型，不需要再进行解码
                                // ch.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {});
                                ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                                ch.pipeline().addLast(new TcpSimple2Message());
                                ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        super.channelRead(ctx, msg);
                                    }
                                });

                            }
                        }).bind().sync().channel();
                FeiQCache.tcpChannelMap.put(ip, channel);
                FeiQCache.tcpEventLoopGroupMap.put(ip, Arrays.asList(bossGroup, workerGroup));
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    public static void close(String closeIp) {
        FeiQCache.tcpChannelMap.forEach((ip, channel) -> {
            try {
                // 关闭全部
                if (StringUtils.isBlank(closeIp)){
                    channel.closeFuture().sync();
                    FeiQCache.tcpChannelMap.remove(ip);
                    FeiQCache.tcpEventLoopGroupMap.get(ip).forEach(AbstractEventExecutorGroup::shutdownGracefully);
                    FeiQCache.tcpEventLoopGroupMap.remove(ip);
                } else if (Objects.equals(ip, closeIp)){
                    channel.closeFuture().sync();
                    FeiQCache.tcpChannelMap.remove(ip);
                    FeiQCache.tcpEventLoopGroupMap.get(ip).forEach(AbstractEventExecutorGroup::shutdownGracefully);
                    FeiQCache.tcpEventLoopGroupMap.remove(ip);
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    public static void close() {
        close(null);
    }
    public static void init() throws InterruptedException {
        FeiQCache.allIps.add("192.168.88.1");
//        FeiQCache.allIps.add("192.168.66.1");
        start();

    }
}
